{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/embeddings/isaacus.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Isaacus Embeddings\n",
    "\n",
    "The `llama-index-embeddings-isaacus` package contains LlamaIndex integrations for building applications with Isaacus' legal AI embedding models. This integration allows you to easily connect to and use the **Kanon 2 Embedder** - the world's most accurate legal embedding model on the [Massive Legal Embedding Benchmark (MLEB)](https://isaacus.com/blog/introducing-mleb).\n",
    "\n",
    "Isaacus embeddings support task-specific optimization:\n",
    "- `task=\"retrieval/query\"`: Optimize embeddings for search queries\n",
    "- `task=\"retrieval/document\"`: Optimize embeddings for documents to be indexed\n",
    "\n",
    "In this notebook, we will demonstrate using Isaacus Embeddings for legal document retrieval."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Installation\n",
    "\n",
    "Install the necessary integrations.\n",
    "\n",
    "If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install llama-index-embeddings-isaacus\n",
    "%pip install llama-index-llms-openai"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install llama-index"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup\n",
    "\n",
    "### Get your Isaacus API key\n",
    "\n",
    "1. Create an account at [Isaacus Platform](https://platform.isaacus.com/accounts/signup/)\n",
    "2. Add a [payment method](https://platform.isaacus.com/billing/) to claim your [free credits](https://docs.isaacus.com/pricing/credits)\n",
    "3. Create an [API key](https://platform.isaacus.com/users/api-keys/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "# Set your Isaacus API key\n",
    "isaacus_api_key = \"YOUR_ISAACUS_API_KEY\"\n",
    "os.environ[\"ISAACUS_API_KEY\"] = isaacus_api_key"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Basic Usage\n",
    "\n",
    "### Get a Single Embedding"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_index.embeddings.isaacus import IsaacusEmbedding\n",
    "\n",
    "# Initialize the Isaacus Embedding model\n",
    "embed_model = IsaacusEmbedding(\n",
    "    api_key=isaacus_api_key,\n",
    "    model=\"kanon-2-embedder\",\n",
    ")\n",
    "\n",
    "# Get a single embedding\n",
    "embedding = embed_model.get_text_embedding(\n",
    "    \"This agreement shall be governed by the laws of Delaware.\"\n",
    ")\n",
    "\n",
    "print(f\"Embedding dimension: {len(embedding)}\")\n",
    "print(f\"First 5 values: {embedding[:5]}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Get Batch Embeddings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get embeddings for multiple legal texts\n",
    "legal_texts = [\n",
    "    \"The parties agree to binding arbitration.\",\n",
    "    \"Confidential information shall not be disclosed.\",\n",
    "    \"This contract may be terminated with 30 days notice.\",\n",
    "]\n",
    "\n",
    "embeddings = embed_model.get_text_embedding_batch(legal_texts)\n",
    "\n",
    "print(f\"Number of embeddings: {len(embeddings)}\")\n",
    "print(f\"Each embedding has {len(embeddings[0])} dimensions\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Task-Specific Embeddings\n",
    "\n",
    "Isaacus embeddings support different tasks for optimal performance:\n",
    "- **`retrieval/document`**: For documents to be indexed\n",
    "- **`retrieval/query`**: For search queries\n",
    "\n",
    "Using the appropriate task improves retrieval accuracy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# For documents (use when indexing)\n",
    "doc_embed_model = IsaacusEmbedding(\n",
    "    api_key=isaacus_api_key,\n",
    "    task=\"retrieval/document\",\n",
    ")\n",
    "\n",
    "doc_embedding = doc_embed_model.get_text_embedding(\n",
    "    \"The Company has the right to terminate this agreement.\"\n",
    ")\n",
    "\n",
    "print(f\"Document embedding dimension: {len(doc_embedding)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# For queries (automatically used by get_query_embedding)\n",
    "query_embedding = embed_model.get_query_embedding(\n",
    "    \"What are the termination conditions?\"\n",
    ")\n",
    "\n",
    "print(f\"Query embedding dimension: {len(query_embedding)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dimensionality Reduction\n",
    "\n",
    "You can reduce the embedding dimensionality for faster search and lower storage costs:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Use reduced dimensions (default is 1792)\n",
    "embed_model_512 = IsaacusEmbedding(\n",
    "    api_key=isaacus_api_key,\n",
    "    dimensions=512,\n",
    ")\n",
    "\n",
    "embedding_512 = embed_model_512.get_text_embedding(\"Legal text example\")\n",
    "\n",
    "print(f\"Reduced embedding dimension: {len(embedding_512)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Full RAG Example with Legal Documents\n",
    "\n",
    "Now let's build a complete RAG pipeline using Isaacus embeddings with a legal document (Uber's 10-K SEC filing)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import logging\n",
    "import sys\n",
    "\n",
    "logging.basicConfig(stream=sys.stdout, level=logging.INFO)\n",
    "logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))\n",
    "\n",
    "from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
    "from llama_index.llms.openai import OpenAI\n",
    "from llama_index.core.response.notebook_utils import display_source_node\n",
    "from IPython.display import Markdown, display"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Download Legal Document Data\n",
    "\n",
    "We'll use Uber's 10-K SEC filing, which contains legal and regulatory information - perfect for demonstrating Kanon 2's legal domain expertise."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!mkdir -p 'data/10k/'\n",
    "!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/10k/uber_2021.pdf' -O 'data/10k/uber_2021.pdf'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Load the Legal Document"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "documents = SimpleDirectoryReader(\"./data/10k/\").load_data()\n",
    "print(f\"Loaded {len(documents)} document(s)\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Build Index with Document Task\n",
    "\n",
    "We use `task=\"retrieval/document\"` when building the index to optimize embeddings for document storage."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Initialize embedding model for documents\n",
    "embed_model = IsaacusEmbedding(\n",
    "    api_key=isaacus_api_key,\n",
    "    model=\"kanon-2-embedder\",\n",
    "    task=\"retrieval/document\",\n",
    ")\n",
    "\n",
    "# Build the index\n",
    "index = VectorStoreIndex.from_documents(\n",
    "    documents=documents,\n",
    "    embed_model=embed_model,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Query with Legal Questions\n",
    "\n",
    "Now we'll query the index with legal-specific questions. Note that `get_query_embedding` automatically uses `task=\"retrieval/query\"` for optimal query performance."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a retriever\n",
    "retriever = index.as_retriever(similarity_top_k=3)\n",
    "\n",
    "# Query about risk factors\n",
    "retrieved_nodes = retriever.retrieve(\n",
    "    \"What are the main risk factors mentioned in the document?\"\n",
    ")\n",
    "\n",
    "print(f\"Retrieved {len(retrieved_nodes)} nodes\\n\")\n",
    "\n",
    "for i, node in enumerate(retrieved_nodes):\n",
    "    print(f\"\\n--- Node {i+1} (Score: {node.score:.4f}) ---\")\n",
    "    display_source_node(node, source_length=500)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Query about Legal Proceedings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Query about legal proceedings\n",
    "retrieved_nodes = retriever.retrieve(\n",
    "    \"What legal proceedings or litigation is the company involved in?\"\n",
    ")\n",
    "\n",
    "print(f\"Retrieved {len(retrieved_nodes)} nodes\\n\")\n",
    "\n",
    "for i, node in enumerate(retrieved_nodes):\n",
    "    print(f\"\\n--- Node {i+1} (Score: {node.score:.4f}) ---\")\n",
    "    display_source_node(node, source_length=500)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Build a Query Engine with LLM\n",
    "\n",
    "Combine Isaacus embeddings with an LLM for complete question answering:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "# Set your OpenAI API key\n",
    "openai_api_key = \"YOUR_OPENAI_API_KEY\"\n",
    "os.environ[\"OPENAI_API_KEY\"] = openai_api_key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set up LLM\n",
    "llm = OpenAI(model=\"gpt-4o-mini\", temperature=0)\n",
    "\n",
    "# Create query engine\n",
    "query_engine = index.as_query_engine(\n",
    "    llm=llm,\n",
    "    similarity_top_k=5,\n",
    ")\n",
    "\n",
    "# Ask a legal question\n",
    "response = query_engine.query(\n",
    "    \"What are the company's main regulatory and legal risks?\"\n",
    ")\n",
    "\n",
    "display(Markdown(f\"**Answer:** {response}\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Another Legal Query"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "response = query_engine.query(\n",
    "    \"What intellectual property does the company rely on?\"\n",
    ")\n",
    "\n",
    "display(Markdown(f\"**Answer:** {response}\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Async Usage\n",
    "\n",
    "Isaacus embeddings also support async operations for better performance in async applications:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import asyncio\n",
    "\n",
    "\n",
    "async def get_embeddings_async():\n",
    "    embed_model = IsaacusEmbedding(\n",
    "        api_key=isaacus_api_key,\n",
    "    )\n",
    "\n",
    "    # Get async single embedding\n",
    "    embedding = await embed_model.aget_text_embedding(\n",
    "        \"Async legal document text\"\n",
    "    )\n",
    "\n",
    "    # Get async batch embeddings\n",
    "    embeddings = await embed_model.aget_text_embedding_batch(\n",
    "        [\"Text 1\", \"Text 2\", \"Text 3\"]\n",
    "    )\n",
    "\n",
    "    return embedding, embeddings\n",
    "\n",
    "\n",
    "# Run async function\n",
    "embedding, embeddings = await get_embeddings_async()\n",
    "\n",
    "print(f\"Async single embedding dimension: {len(embedding)}\")\n",
    "print(\n",
    "    f\"Async batch: {len(embeddings)} embeddings of {len(embeddings[0])} dimensions each\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Summary\n",
    "\n",
    "In this notebook, we demonstrated:\n",
    "\n",
    "1. **Basic usage** - Getting single and batch embeddings\n",
    "2. **Task-specific optimization** - Using `retrieval/document` for indexing and `retrieval/query` for searching\n",
    "3. **Dimensionality reduction** - Reducing embedding size for efficiency\n",
    "4. **Legal RAG pipeline** - Building a complete retrieval system with legal documents (Uber 10-K)\n",
    "5. **Async operations** - Using async methods for better performance\n",
    "\n",
    "The Kanon 2 Embedder excels at legal document understanding and retrieval, making it ideal for legal tech applications, compliance tools, contract analysis, and more.\n",
    "\n",
    "## Additional Resources\n",
    "\n",
    "- [Isaacus Documentation](https://docs.isaacus.com)\n",
    "- [Kanon 2 Embedder Announcement](https://isaacus.com/blog/introducing-kanon-2-embedder)\n",
    "- [Massive Legal Embedding Benchmark (MLEB)](https://isaacus.com/blog/introducing-mleb)\n",
    "- [Isaacus Platform](https://platform.isaacus.com)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
